let uid = 0;
export default class Watcher {
  constructor(vm, expOrFn, cb, options) {
    // 观察者实例 vm属性 指明观察者属于哪个组件实例
    this.vm = vm;
    vm._watchers.push(this);
    if (options) {
      this.deep = !!options.deep; // 当前观察者实例对象是否是深度观测
      this.lazy = !!options.lazy;
      this.sync = !!options.sync; // 告诉观察者当数据变化时是否同步求值并执行回调
    } else {
      this.deep = this.user = this.lazy = this.sync = false;
    }
    this.cb = cb;
    // 避免收集重复依赖，且移除无用依赖
    this.dirty = this.lazy;
    this.id = ++uid;
    this.deps = [];
    this.newDeps = [];
    this.depIds = new Set();
    this.newDepIds = new Set();
    this.getter = expOrFn;
    this.value = this.lazy ? undefined : this.get();
  }
  get() {
    // 推送当前Watcher实例到Dep.target
    pushTarget(this);
    let value;
    const vm = this.vm;
    value = this.getter.call(vm, vm);
    if (this.deep) {
      traverse(value); // 递归地读取被观察属性的所有子属性的值
    }
    popTarget(); // 从Dep.target 删除
    this.cleanupDeps();
    return value;
  }
}
